#ifndef _VECTOR_H

#define _VECTOR_H 1//这里参照的是stl_vector.h源文件的写法
#define SPARE_CAPACITY 256//为了push_back时尽可能少的reserve，这里将SPARE_CAPACITY设为256，并以宏来定义

#include <algorithm>
#include <iostream>

template<class Object>class Vector
{
//私有成员的声明
private:
    int theSize;
    int theCapacity;
    Object* objects;
public:
//这里共涉及含参构造函数和拷贝构造函数，其中拷贝构造函数的参数可以是左值引用或者右值引用，但必须为const,需要重载不同版本
    explicit Vector(int initSize=0): theSize{initSize},theCapacity{initSize+ SPARE_CAPACITY}
    {objects = new Object[theCapacity];}

    Vector(const Vector &rhs): theSize{rhs.theSize},theCapacity{rhs.theCapacity},objects{nullptr}
    {
        objects=new Object[theCapacity];
        for(int k=0;k<theSize;++k)
            objects[k]=rhs.objects[k];
    }
//重载"=",同样需要重载左值引用和右值引用两个版本
    Vector& operator= (const Vector &rhs)
    {
        Vector copy=rhs;
        std::swap(*this,copy);//swap函数实现更加便捷
        return *this;
    }

    Vector(Vector &&rhs): theSize{rhs.theSize},theCapacity{rhs.theCapacity},objects{rhs.objects}
    {
        rhs.objects=nullptr;
        rhs.theSize=0;
        rhs.theCapacity=0;
    }

    Vector& operator=(Vector &&rhs)
    {
        std::swap(theSize,rhs.theSize);
        std::swap(theCapacity,rhs.theCapacity);
        std::swap(objects,rhs.objects);
        return *this;
    }
//resize函数需要判断newSize与theCapacity的大小，并决定是否开辟新的空间，开辟新空间时直接开成newSize的两倍大小，留出剩余空间以防push_back时需要增设新的空间
    void resize(int newSize)
    {
        if(newSize>theCapacity)
            reserve(newSize*2);
        theSize=newSize;
    }
//reserve函数根据newCapacity的大小决定是否开辟新的空间
    void reserve(int newCapacity)
    {
        if(newCapacity<theSize)
            return;
        Object *newArray=new Object[newCapacity];
        for(int k=0;k<theSize;++k)
            newArray[k]=std::move(objects[k]);
        theCapacity=newCapacity;
        std::swap(objects,newArray);
        delete [] newArray;
    }
//析构函数，删除new开辟的内存
     ~Vector()
    {delete [] objects;}
//重载"[]"，分为const和non-const两个版本
    Object& operator[](int index){return objects[index];}

    const Object& operator[](int index)const {return objects[index];}

    bool empty() const{return size()==0;}
    int size() const{return theSize;}
    int capacity() const{return theCapacity;}
//实现尾端插入，这里需重载常值引用，左值引用和右值引用三个版本，若插入后超出容量，则需reserve来开辟新的内存空间，report中会讨论为什么这里开辟双倍大小的空间
    void push_back(const Object& x)
    {
        if(theSize==theCapacity)
            reserve(2*theCapacity+1);
        objects[theSize++]=std::move(x);
    }

    void push_back(Object& x)
    {
        if(theSize==theCapacity)
            reserve(2*theCapacity+1);
        objects[theSize++]=std::move(x);
    }

    void push_back(Object&& x)
    {
        if(theSize==theCapacity)
            reserve(2*theCapacity+1);
        objects[theSize++]=std::move(x);
    }
//实现尾端删除，因objects的内存统一释放，这里只需要将Size-1即可
    void pop_back()
    {
        --theSize;
    }
//实现尾端查找
    const Object& back() const
    {
        return objects[theSize-1];
    }
//迭代器的实现，可执行++运算，便于遍历查找，并完成begin,end各两个版本（const/non-const）的迭代器返回的实现
    typedef Object* iterator;
    typedef const Object* const_iterator;
    iterator begin() {return &objects[0];}
    const_iterator begin() const {return &objects[0];}
    iterator end() {return &objects[size()];}
    const_iterator end() const {return &objects[size()];}
};
//重载输出流，方便输出，分const与non-const两个版本
template<class Object> std::ostream& operator <<(std::ostream& out,const Vector<Object>& A)
{
    if(A.size()==0) out<<"empty Vector";
    else{
        out<< "(";
        for(int i=0;i<A.size();++i){
            out<<A[i];
            if(i!=(A.size()-1)) out<<",";
        }
        out<<")";
    }
    return out;
}

template<class Object> std::ostream& operator <<(std::ostream& out,Vector<Object>& A)
{
    if(A.size()==0) out<<"empty Vector";
    else{
        out<< "(";
        for(int i=0;i<A.size();++i){
            out<<A[i];
            if(i!=(A.size()-1)) out<<",";
        }
        out<<")";
    }
    return out;
}

#else
#endif
